package conf

import (
	"encoding/json"
	"github.com/bytedance/go-tagexpr/v2/validator"
	"github.com/cloudwego/hertz/pkg/common/hlog"
	"gopkg.in/yaml.v2"
	"login/src/tables"
	"os"
	"path/filepath"
	"sync"
)

var (
	conf *Config
	once sync.Once

	GridData []map[string]interface{}
)

type Config struct {
	Env      string
	Jwt      Jwt      `yaml:"jwt"`
	Server   Server   `yaml:"server"`
	MySQL    MySQL    `yaml:"mysql"`
	Redis    Redis    `yaml:"redis"`
	Mongo    Mongo    `yaml:"mongo"`
	Registry Registry `yaml:"registry"`
	Google   Google   `yaml:"google"`
	Log      Log      `yaml:"log"`
}

type Google struct {
	ClientID     string `yaml:"client_id"`
	ClientSecret string `yaml:"client_secret"`
	RedirectURL  string `yaml:"redirect_url"`
}

type Jwt struct {
	SecretKey string `yaml:"secret_key"`
}

type MySQL struct {
	DSN string `yaml:"dsn"`
}

type Mongo struct {
	URI string `yaml:"uri"`
}

type Redis struct {
	Address  string `yaml:"address"`
	Username string `yaml:"username"`
	Password string `yaml:"password"`
	DB       int    `yaml:"db"`
}

type Astrology struct {
	UserId string `yaml:"user_id"`
	ApiKey string `yaml:"api_key"`
	Url    string `yaml:"url"`
}

type OpenAI struct {
	Url    string `yaml:"url"`
	ApiKey string `yaml:"api_key"`
}

type Log struct {
	Dir          string `yaml:"dir"`
	Level        string `yaml:"level"`
	AccessLogFmt string `yaml:"access_log_fmt"`
}

type Server struct {
	Address         string `yaml:"address"`
	EnablePprof     bool   `yaml:"enable_pprof"`
	EnableGzip      bool   `yaml:"enable_gzip"`
	EnableAccessLog bool   `yaml:"enable_access_log"`
	LogLevel        string `yaml:"log_level"`
	LogFileName     string `yaml:"log_file_name"`
	LogMaxSize      int    `yaml:"log_max_size"`
	LogMaxBackups   int    `yaml:"log_max_backups"`
	LogMaxAge       int    `yaml:"log_max_age"`
}

type Registry struct {
	RegistryAddress []string `yaml:"registry_address"`
	Username        string   `yaml:"username"`
	Password        string   `yaml:"password"`
}

// GetConf gets configuration instance
func GetConf() *Config {
	return conf
}

func Init() {
	once.Do(initConf)
}

func initConf() {
	// 加载服务器配置
	prefix := "conf"
	confFileRelPath := filepath.Join(prefix, filepath.Join(GetEnv(), "conf.yaml"))
	content, err := os.ReadFile(confFileRelPath)
	if err != nil {
		panic(err)
	}
	conf = new(Config)
	err = yaml.Unmarshal(content, conf)
	if err != nil {
		panic(err)
	}
	if err := validator.Validate(conf); err != nil {
		panic(err)
	}
	conf.Env = GetEnv()

	// 加载策划配置
	if tables, err := tables.NewTables(loader); err != nil {
		println(err.Error())
	} else {
		hlog.Infof("%v", tables.TabManifestRewards.GetDataList()[0])
	}

	GridData, _ = loadGridData()

	hlog.Infof("%v", GridData)
}

func loadGridData() ([]map[string]interface{}, error) {
	if bytes, err := os.ReadFile("./res/GridData.json"); err != nil {
		return nil, err
	} else {
		jsonData := make([]map[string]interface{}, 0)
		if err = json.Unmarshal(bytes, &jsonData); err != nil {
			return nil, err
		}
		return jsonData, nil
	}
}

func loader(file string) ([]map[string]interface{}, error) {
	if bytes, err := os.ReadFile("./res/tables/" + file + ".json"); err != nil {
		return nil, err
	} else {
		jsonData := make([]map[string]interface{}, 0)
		if err = json.Unmarshal(bytes, &jsonData); err != nil {
			return nil, err
		}
		return jsonData, nil
	}
}

func GetEnv() string {
	e := os.Getenv("GO_ENV")
	if len(e) == 0 {
		return "dev"
	}
	return e
}
